home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / term / term_47a_pch.lha / Source / term-4.7a / StatusDisplay.c < prev    next >
C/C++ Source or Header  |  1996-11-02  |  29KB  |  1,324 lines

  1. /*
  2. **    StatusDisplay.c
  3. **
  4. **    Status information display routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* The information to be displayed. */
  17.  
  18. enum    {
  19.             INFO_STATUS,INFO_BUFFER,INFO_PROTOCOL,INFO_EMULATION,INFO_BAUDRATE,
  20.             INFO_PARAMETERS,INFO_CURRENTTIME,INFO_ONLINETIME,INFO_ONLINECOST,
  21.             INFO_UNITTIME
  22.         };
  23.  
  24.     /* The current status line display mode. */
  25.  
  26. enum    {
  27.             MODE_SCREEN_NORMAL,MODE_SCREEN_COMPRESSED,
  28.             MODE_WB_NORMAL,MODE_WB_COMPRESSED
  29.         };
  30.  
  31.     /* Enumerated text boxes. */
  32.  
  33. enum    {
  34.             STATUSBOX_STATUS_FONT,STATUSBOX_PROTOCOL_TERMINAL,
  35.             STATUSBOX_RATE_PARAMETERS,STATUSBOX_TIME_ONLINE
  36.         };
  37.  
  38.     /* What to show in the online time box. */
  39.  
  40. enum    {
  41.             SHOW_Cost,SHOW_OnlineTime,SHOW_UnitTime
  42.         };
  43.  
  44.     /* The status server passes this structure to the
  45.      * rendering routine if the status information
  46.      * is to be updated.
  47.      */
  48.  
  49. struct ObjectCarrier
  50. {
  51.     struct RastPort     *RPort;
  52.     LONG              FirstColumn,
  53.                       FullWidth;
  54.     struct TextBox    **BoxArray,
  55.                      *BoxList;
  56. };
  57.  
  58.     /* A custom message type for the display update server. */
  59.  
  60. struct UpdateMessage
  61. {
  62.     struct Message    Message;
  63.  
  64.     APTR            Object;
  65.     UBYTE            Mode,
  66.                     Type;
  67. };
  68.  
  69.     /* The following static strings are displayed in the status
  70.      * window.
  71.      */
  72.  
  73. STATIC STRPTR             ConfigBufferState[3],
  74.                          ConfigEmulation[6],
  75.                          ConfigParity[6];
  76.  
  77.     /* The status modes and the corresponding text IDs. */
  78.  
  79. STATIC LONG ConfigStatusIDs[] =
  80. {
  81.     MSG_TERMAUX_READY_TXT,
  82.     MSG_TERMAUX_HOLDING_TXT,
  83.     MSG_TERMAUX_DIALING_TXT,
  84.     MSG_TERMAUX_UPLOAD_TXT,
  85.     MSG_TERMAUX_DOWNLOAD_TXT,
  86.     MSG_TERMAUX_BREAKING_TXT,
  87.     MSG_TERMAUX_HANG_UP_TXT,
  88.     MSG_TERMAUX_RECORD_TXT,
  89.     MSG_AREXX_RUNNING_TXT
  90. };
  91.  
  92.     /* Width of the status line text, required in case the user interface
  93.      * font happens to be proportional-spaced.
  94.      */
  95.  
  96. STATIC LONG                 StatusLineWidth;
  97.  
  98.     /* The status display update task. */
  99.  
  100. STATIC struct Task        *StatusDisplayTask;
  101. STATIC struct MsgPort    *StatusDisplayPort;
  102.  
  103.     /* Display update data */
  104.  
  105. STATIC WORD                 UpdateSig;
  106. STATIC ULONG             UpdateMask;
  107. STATIC BOOL                 NeedFullRefresh;
  108.  
  109. STATIC VOID
  110. DrawSeparator(struct RastPort *RPort)
  111. {
  112.     SetAPen(RPort,Pens[SHADOWPEN]);
  113.     RectFill(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayLeft + StatusDisplayWidth - 1,StatusDisplayTop);
  114.  
  115.     SetAPen(RPort,Pens[SHINEPEN]);
  116.     RectFill(RPort,StatusDisplayLeft,StatusDisplayTop + 1,StatusDisplayLeft + StatusDisplayWidth - 1,StatusDisplayTop + 1);
  117. }
  118.  
  119.     /* DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
  120.      *
  121.      *    Display information in the status line area.
  122.      */
  123.  
  124. STATIC VOID
  125. DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
  126. {
  127.         /* What mode of operation is the status area in? */
  128.  
  129.     switch(Mode)
  130.     {
  131.             /* Compressed mode. */
  132.  
  133.         case MODE_SCREEN_COMPRESSED:
  134.         {
  135.             struct RastPort *RPort = Object;
  136.  
  137.             STATIC BYTE Offsets[8] =
  138.             {
  139.                  0,
  140.                 -1,    /* Not supported */
  141.                 26,
  142.                 11,
  143.                 40,
  144.                 53,
  145.                 61,
  146.                 72
  147.             };
  148.  
  149.             STATIC UBYTE Strings[8][20];
  150.             UBYTE LineBuffer[90];
  151.             LONG i,j,k,Width;
  152.  
  153.             strcpy(Strings[Type],String);
  154.  
  155.             strcpy(LineBuffer,"         ·              ·             ·            ·       ·          ·         ");
  156.  
  157.             for(i = 0 ; i < 8 ; i++)
  158.             {
  159.                 if(Offsets[i] >= 0)
  160.                 {
  161.                     j = strlen(Strings[i]);
  162.  
  163.                     for(k = 0 ; k < j ; k++)
  164.                         LineBuffer[Offsets[i] + k] = Strings[i][k];
  165.                 }
  166.             }
  167.  
  168.             Width = TextLength(RPort,LineBuffer,80);
  169.  
  170.             if((StatusLineWidth && StatusLineWidth != Width) || NeedFullRefresh)
  171.             {
  172.                 LONG OldPen = ReadAPen(RPort);
  173.  
  174.                 SetAPen(RPort,Pens[TEXTPEN]);
  175.                 FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  176.                 SetAPen(RPort,OldPen);
  177.  
  178.                 StatusLineWidth = Width;
  179.                 NeedFullRefresh = FALSE;
  180.             }
  181.  
  182.             PlaceText(RPort,StatusDisplayLeft + (StatusDisplayWidth - Width) / 2,StatusDisplayTop,LineBuffer,80);
  183.         }
  184.  
  185.         break;
  186.  
  187.             /* Normal mode. */
  188.  
  189.         case MODE_SCREEN_NORMAL:
  190.         {
  191.             STATIC UBYTE Codes[8][2] =
  192.             {
  193.                 STATUSBOX_STATUS_FONT,            0,
  194.                 STATUSBOX_STATUS_FONT,            1,
  195.  
  196.                 STATUSBOX_PROTOCOL_TERMINAL,    0,
  197.                 STATUSBOX_PROTOCOL_TERMINAL,    1,
  198.  
  199.                 STATUSBOX_RATE_PARAMETERS,        0,
  200.                 STATUSBOX_RATE_PARAMETERS,        1,
  201.  
  202.                 STATUSBOX_TIME_ONLINE,            0,
  203.                 STATUSBOX_TIME_ONLINE,            1
  204.             };
  205.  
  206.             struct ObjectCarrier *Carrier = (struct ObjectCarrier *)Object;
  207.  
  208.             if(Carrier->RPort)
  209.             {
  210.                 if(NeedFullRefresh && !Config->ScreenConfig->SplitStatus)
  211.                 {
  212.                     struct RastPort    *RPort = Carrier->RPort;
  213.                     LONG             Left;
  214.  
  215.                     if((Left = StatusDisplayLeft + (StatusDisplayWidth - Carrier->FullWidth) / 2) < 0)
  216.                         Left = 0;
  217.  
  218.                     Left += Carrier->FirstColumn - SZ_GetBoxInfo(Carrier->BoxList,BOX_LEFT);
  219.  
  220.                     SetAPen(RPort,Pens[BACKGROUNDPEN]);
  221.                     FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  222.  
  223.                     DrawSeparator(RPort);
  224.  
  225.                     SZ_SetBoxes(Carrier->BoxList,-1,StatusDisplayTop + 3);
  226.                     SZ_MoveBoxes(Carrier->BoxList,Left,0);
  227.  
  228.                     SZ_DrawBoxes(RPort,Carrier->BoxList);
  229.  
  230.                     NeedFullRefresh = FALSE;
  231.                 }
  232.  
  233.                 SZ_PrintLine(Carrier->RPort,Carrier->BoxArray[Codes[Type][0]],Codes[Type][1],String);
  234.             }
  235.         }
  236.  
  237.         break;
  238.     }
  239. }
  240.  
  241.     /* DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
  242.      *
  243.      *    Post an update message to the status display server.
  244.      */
  245.  
  246. STATIC VOID
  247. DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
  248. {
  249.     struct UpdateMessage    *Msg;
  250.     LONG                     Len = strlen(String) + 1;
  251.  
  252.         /* Allocate enough space to hold both the string
  253.          * and the message.
  254.          */
  255.  
  256.     if(Msg = (struct UpdateMessage *)AllocVecPooled(sizeof(struct UpdateMessage) + Len,MEMF_ANY | MEMF_CLEAR))
  257.     {
  258.             /* Fill in the message head. */
  259.  
  260.         Msg->Message.mn_Length = sizeof(struct UpdateMessage) + Len;
  261.  
  262.             /* Set up the name pointer. */
  263.  
  264.         Msg->Message.mn_Node.ln_Name = (STRPTR)(Msg + 1);
  265.  
  266.             /* Copy the string. */
  267.  
  268.         strcpy(Msg->Message.mn_Node.ln_Name,String);
  269.  
  270.             /* Fill in the remaining data. */
  271.  
  272.         Msg->Object    = Object;
  273.         Msg->Mode        = Mode;
  274.         Msg->Type        = Type;
  275.  
  276.             /* Post the message. */
  277.  
  278.         PutMsg(StatusDisplayPort,(struct Message *)Msg);
  279.     }
  280. }
  281.  
  282.     /* UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...):
  283.      *
  284.      *    Update the information displayed in the status
  285.      *    area.
  286.      */
  287.  
  288. STATIC VOID
  289. UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...)
  290. {
  291.     if(Object)
  292.     {
  293.         UBYTE     MiniBuffer[50];
  294.         STRPTR    *String;
  295.         LONG    *Numeral;
  296.         va_list     VarArgs;
  297.  
  298.         va_start(VarArgs,Type);
  299.  
  300.         String    = (STRPTR *)VarArgs;
  301.         Numeral    = (LONG *)VarArgs;
  302.  
  303.         switch(Type)
  304.         {
  305.             case INFO_STATUS:
  306.  
  307.                 LimitedStrcpy(sizeof(MiniBuffer),MiniBuffer,LocaleString(ConfigStatusIDs[Numeral[0]]));
  308.                 LimitedStrcat(sizeof(MiniBuffer),MiniBuffer,"         ");
  309.  
  310.                 MiniBuffer[9] = 0;
  311.  
  312.                 break;
  313.  
  314.             case INFO_BUFFER:
  315.  
  316.                 if(Mode == MODE_SCREEN_NORMAL)
  317.                     DoInfo(Object,Mode,Type,ConfigBufferState[Numeral[0]]);
  318.  
  319.                 va_end(VarArgs);
  320.  
  321.                 return;
  322.  
  323.             case INFO_UNITTIME:
  324.  
  325.                 LimitedSPrintf(sizeof(MiniBuffer) - 1,&MiniBuffer[1],"%2ld:%02ld",Numeral[0] / 60,Numeral[0] % 60);
  326.  
  327.                 if(Numeral[0] > 0)
  328.                     MiniBuffer[0] = '-';
  329.                 else
  330.                     MiniBuffer[0] = ' ';
  331.  
  332.                 Type = INFO_ONLINETIME;
  333.  
  334.                 break;
  335.  
  336.             case INFO_ONLINECOST:
  337.  
  338.                 CopyMem(String[0],MiniBuffer,8);
  339.                 LimitedStrcat(sizeof(MiniBuffer),MiniBuffer,"          ");
  340.  
  341.                 MiniBuffer[8] = 0;
  342.  
  343.                 Type = INFO_ONLINETIME;
  344.  
  345.                 break;
  346.  
  347.             case INFO_CURRENTTIME:
  348.  
  349.                 FormatTime(MiniBuffer,sizeof(MiniBuffer),Numeral[0],Numeral[1],Numeral[2]);
  350.                 break;
  351.  
  352.             case INFO_ONLINETIME:
  353.  
  354.                 LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%02ld:%02ld:%02ld",Numeral[0],Numeral[1],Numeral[2]);
  355.                 break;
  356.  
  357.             case INFO_BAUDRATE:
  358.  
  359.                 if(LocaleBase)
  360.                     LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%lD        ",Numeral[0]);
  361.                 else
  362.                     LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%ld        ",Numeral[0]);
  363.  
  364.                 MiniBuffer[7] = 0;
  365.  
  366.                 break;
  367.  
  368.             case INFO_PROTOCOL:
  369.             case INFO_EMULATION:
  370.  
  371.                 CopyMem(String[0],MiniBuffer,12);
  372.                 LimitedStrcat(sizeof(MiniBuffer),MiniBuffer,"           ");
  373.  
  374.                 MiniBuffer[12] = 0;
  375.  
  376.                 break;
  377.  
  378.             case INFO_PARAMETERS:
  379.  
  380.                 if(Mode == MODE_SCREEN_COMPRESSED)
  381.                 {
  382.                     STATIC UBYTE Parities[5] =
  383.                     {
  384.                         'N','E','O','M','S'
  385.                     };
  386.  
  387.                     LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%ld-%lc-%ld",Numeral[0],Parities[Numeral[1]],Numeral[2]);
  388.                 }
  389.                 else
  390.                     LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%ld-%s-%ld",Numeral[0],ConfigParity[Numeral[1]],Numeral[2]);
  391.  
  392.                 break;
  393.         }
  394.  
  395.         DoInfo(Object,Mode,Type,MiniBuffer);
  396.  
  397.         va_end(VarArgs);
  398.     }
  399. }
  400.  
  401.     /* VisualBeep():
  402.      *
  403.      *    Handle the visual part of the display beep.
  404.      */
  405.  
  406. STATIC BOOL
  407. VisualBeep(ColourTable **OldPtr,ColourTable **NewPtr)
  408. {
  409.     ColourTable *Old,*New;
  410.  
  411.     Old = CreateColourTable(Window->WScreen->ViewPort.ColorMap->Count,NULL,NULL);
  412.     New = CreateColourTable(Window->WScreen->ViewPort.ColorMap->Count,NULL,NULL);
  413.  
  414.     if(New && Old)
  415.     {
  416.         ULONG Red,Green,Blue;
  417.         LONG i;
  418.  
  419.         GrabColours(&Window->WScreen->ViewPort,Old);
  420.         CopyColours(Old,New);
  421.  
  422.         for(i = 0 ; i < Old->NumColours ; i++)
  423.         {
  424.             Red        = (Old->Entry[i].Red     >> 24) + 64;
  425.             Green    = (Old->Entry[i].Green     >> 24) + 64;
  426.             Blue    = (Old->Entry[i].Blue     >> 24) + 64;
  427.  
  428.             if(Red > 255)
  429.                 Red = 255;
  430.  
  431.             if(Green > 255)
  432.                 Green = 255;
  433.  
  434.             if(Blue > 255)
  435.                 Blue = 255;
  436.  
  437.             New->Entry[i].Red    = SPREAD(Red);
  438.             New->Entry[i].Green    = SPREAD(Green);
  439.             New->Entry[i].Blue    = SPREAD(Blue);
  440.         }
  441.  
  442.         *OldPtr = Old;
  443.         *NewPtr = New;
  444.  
  445.         return(TRUE);
  446.     }
  447.  
  448.     DeleteColourTable(Old);
  449.     DeleteColourTable(New);
  450.  
  451.     *OldPtr = *NewPtr = NULL;
  452.  
  453.     return(FALSE);
  454. }
  455.  
  456.     /* StatusDisplayServer(VOID):
  457.      *
  458.      *    Yet another asynchronous background task to display
  459.      *    some information.
  460.      */
  461.  
  462. STATIC VOID SAVE_DS
  463. StatusDisplayServer(VOID)
  464. {
  465.         /* Create the interface port. */
  466.  
  467.     if(StatusDisplayPort = CreateMsgPort())
  468.     {
  469.         struct UpdateMessage    *Msg;
  470.         ULONG                     Signals;
  471.  
  472.             /* Ring back... */
  473.  
  474.         Signal((struct Task *)StatusProcess,SIG_HANDSHAKE);
  475.  
  476.             /* Wait for messages or termination signal. */
  477.  
  478.         FOREVER
  479.         {
  480.             Signals = Wait(SIG_KILL | PORTMASK(StatusDisplayPort));
  481.  
  482.                 /* Termination? */
  483.  
  484.             if(Signals & SIG_KILL)
  485.                 break;
  486.  
  487.                 /* Message arrival? */
  488.  
  489.             if(Signals & PORTMASK(StatusDisplayPort))
  490.             {
  491.                     /* Process all pending messages. */
  492.  
  493.                 while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
  494.                 {
  495.                     DoStatusInfo(Msg->Object,Msg->Mode,Msg->Type,Msg->Message.mn_Node.ln_Name);
  496.  
  497.                     FreeVecPooled(Msg);
  498.                 }
  499.             }
  500.         }
  501.  
  502.             /* Remove all pending messages. */
  503.  
  504.         while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
  505.             FreeVecPooled(Msg);
  506.  
  507.             /* Remove the msgport. */
  508.  
  509.         DeleteMsgPort(StatusDisplayPort);
  510.     }
  511.  
  512.         /* Lock & quit... */
  513.  
  514.     Forbid();
  515.  
  516.     StatusDisplayTask = NULL;
  517.  
  518.     Signal((struct Task *)StatusProcess,SIG_HANDSHAKE);
  519.  
  520.     RemTask(NULL);
  521. }
  522.  
  523.     /* StatusServer():
  524.      *
  525.      *    Asynchronous process to continuosly display the current
  526.      *    terminal settings.
  527.      */
  528.  
  529. VOID SAVE_DS
  530. StatusServer()
  531. {
  532.     STATIC struct timeval     DeltaTime,
  533.                              LastTime,
  534.                              PeriodTime;
  535.     STATIC LONG                 BeepCount;
  536.  
  537.     STATIC BOOL                 LocalWasOnline;
  538.  
  539.     BOOL                     LocalIsOnline;
  540.  
  541.     BOOL                     PeriodAction;
  542.  
  543.     struct TextBox            *BoxArray[4],
  544.                             *BoxList = NULL,
  545.                             *Box;
  546.  
  547.     struct RastPort            *RPort;
  548.  
  549.     APTR                     SomeObject;
  550.     struct ObjectCarrier     Carrier;
  551.  
  552.     struct timerequest        *StatusTimeRequest;
  553.     struct MsgPort            *StatusTimePort;
  554.     struct timeval             Now;
  555.  
  556.     BOOL                     Background            = FALSE,
  557.                              FlashIt            = FALSE,
  558.                              SetColours            = FALSE,
  559.                              StandardColours    = TRUE,
  560.                              KeepGoing            = TRUE,
  561.                              Beeping            = FALSE;
  562.  
  563.     WORD                     StatusMode            = Config->ScreenConfig->StatusLine;
  564.     WORD                     ShowCounter        = 0;
  565.  
  566.     UBYTE                     LastProtocol[MAX_FILENAME_LENGTH],
  567.                              LastEmulationName[MAX_FILENAME_LENGTH];
  568.  
  569.     LONG                     LastFrozen            = -1,
  570.                              LastEmulation        = -1,
  571.                              LastBitsPerChar    = -1,
  572.                              LastParity            = -1,
  573.                              LastStopBits        = -1,
  574.                              LastStatus            = -1;
  575.  
  576.     LONG                     LastBaud            = -1;
  577.  
  578.     LONG                     i,
  579.                              ThisHour,
  580.                              ThisMinute,
  581.                              BoxCounter = 0,
  582.                              FullWidth;
  583.     LONG                     ColumnLeft[4],
  584.                              ColumnWidth[4],
  585.                              Max,
  586.                              Len;
  587.  
  588.     ColourTable                *Old = NULL,
  589.                             *New = NULL;
  590.  
  591.     BOOL                     AllFine = TRUE;
  592.     LONG                     Mode;
  593.  
  594.     StatusLineWidth = 0;
  595.  
  596.     LastProtocol[0] = 0;
  597.  
  598.     LastEmulationName[0] = 0;
  599.  
  600.     LocalizeString(ConfigBufferState,MSG_TERMSTATUSDISPLAY_FROZEN_TXT,MSG_TERMSTATUSDISPLAY_RECORDING_TXT);
  601.     LocalizeString(ConfigEmulation,MSG_TERMAUX_ANSI_VT102_TXT,MSG_TERMAUX_HEX_TXT);
  602.     LocalizeString(ConfigParity,MSG_TERMAUX_NONE_TXT,MSG_TERMAUX_SPACE_TXT);
  603.  
  604.     if(StatusWindow)
  605.         RPort = StatusWindow->RPort;
  606.     else
  607.         RPort = StatusRPort;
  608.  
  609.     if(RPort)
  610.     {
  611.         SetAPen(RPort,Pens[BACKGROUNDPEN]);
  612.         FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  613.  
  614.             /* Render the information. */
  615.  
  616.         if(StatusWindow)
  617.             SZ_SizeSetup(StatusWindow->WScreen,(struct TextAttr *)&UserFont);
  618.         else
  619.             SZ_SizeSetup(Window->WScreen,(struct TextAttr *)&UserFont);
  620.  
  621.         if(StatusMode == STATUSLINE_COMPRESSED)
  622.         {
  623.             StatusOffset = (StatusDisplayWidth - 80 * UserFontWidth) / 2;
  624.  
  625.             SetAPen(RPort,Pens[TEXTPEN]);
  626.             FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  627.  
  628.             SetPens(RPort,Pens[BACKGROUNDPEN],Pens[TEXTPEN],JAM2);
  629.  
  630.             SetFont(RPort,UserTextFont);
  631.         }
  632.         else
  633.         {
  634.             SetBPen(RPort,Pens[BACKGROUNDPEN]);
  635.  
  636.                 /* Draw a separating line. */
  637.  
  638.             if(!Config->ScreenConfig->SplitStatus)
  639.                 DrawSeparator(RPort);
  640.  
  641.             SetAPen(RPort,Pens[TEXTPEN]);
  642.  
  643.             ColumnLeft[0] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_STATUS_TXT,MSG_TERMSTATUSDISPLAY_FONT_TXT,-1);
  644.             ColumnLeft[1] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT,MSG_TERMSTATUSDISPLAY_TERMINAL_TXT,-1);
  645.             ColumnLeft[2] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT,MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT,-1);
  646.             ColumnLeft[3] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_TIME_TXT,MSG_TERMSTATUSDISPLAY_ONLINE_TXT,-1);
  647.  
  648.             Max = 0;
  649.  
  650.             for(i = 0 ; i < NUM_ELEMENTS(ConfigStatusIDs) ; i++)
  651.             {
  652.                 if((Len = SZ_BoxWidth(strlen(LocaleString(ConfigStatusIDs[i])))) > Max)
  653.                     Max = Len;
  654.             }
  655.  
  656.             for(i = 0 ; ConfigBufferState[i] ; i++)
  657.             {
  658.                 if((Len = SZ_BoxWidth(strlen(ConfigBufferState[i]))) > Max)
  659.                     Max = Len;
  660.             }
  661.  
  662.             ColumnWidth[0] = Max;
  663.  
  664.             Max = SZ_BoxWidth(12);
  665.  
  666.             for(i = 0 ; ConfigEmulation[i] ; i++)
  667.             {
  668.                 if((Len = SZ_BoxWidth(strlen(ConfigEmulation[i]))) > Max)
  669.                     Max = Len;
  670.             }
  671.  
  672.             ColumnWidth[1] = Max;
  673.  
  674.             Max = SZ_BoxWidth(10);
  675.  
  676.             for(i = 0 ; ConfigParity[i] ; i++)
  677.             {
  678.                 if((Len = SZ_BoxWidth(4 + strlen(ConfigParity[i]))) > Max)
  679.                     Max = Len;
  680.             }
  681.  
  682.             ColumnWidth[2] = Max;
  683.  
  684.             ColumnWidth[3] = SZ_BoxWidth(8);
  685.  
  686.             FullWidth = 0;
  687.  
  688.             for(i = 0 ; i < 4 ; i++)
  689.                 FullWidth += ColumnWidth[i] + ColumnLeft[i];
  690.  
  691.             FullWidth += 4 + 3 * InterWidth;
  692.  
  693.             Carrier.FullWidth    = FullWidth;
  694.             Carrier.FirstColumn    = ColumnLeft[0] + 2;
  695.  
  696.             if(!Config->ScreenConfig->SplitStatus)
  697.             {
  698.                 if(FullWidth > StatusDisplayWidth)
  699.                     SZ_SetLeftEdge(StatusDisplayLeft + ColumnLeft[0] + 2);
  700.                 else
  701.                     SZ_SetLeftEdge(StatusDisplayLeft + (StatusDisplayWidth - FullWidth) / 2 + ColumnLeft[0] + 2);
  702.  
  703.                 SZ_SetAbsoluteTop(StatusDisplayTop + 3);
  704.                 SZ_SetTopEdge(StatusDisplayTop + 3);
  705.             }
  706.             else
  707.             {
  708.                 SZ_SetLeftEdge(StatusDisplayLeft + ColumnLeft[0] + 2);
  709.  
  710.                 SZ_SetAbsoluteTop(StatusDisplayTop + 1);
  711.                 SZ_SetTopEdge(StatusDisplayTop + 1);
  712.             }
  713.  
  714.             SZ_SetWidth(ColumnWidth[0]);
  715.  
  716.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  717.                 SZ_Lines,        2,
  718.                 SZ_AutoWidth,    TRUE,
  719.             TAG_DONE);
  720.  
  721.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_STATUS_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_FONT_TXT),NULL);
  722.  
  723.             SZ_SetWidth(ColumnWidth[1]);
  724.             SZ_AddLeftOffset(ColumnLeft[1]);
  725.  
  726.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  727.                 SZ_Lines,        2,
  728.                 SZ_AutoWidth,    TRUE,
  729.                 SZ_NewColumn,    TRUE,
  730.             TAG_DONE);
  731.  
  732.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_TERMINAL_TXT),NULL);
  733.  
  734.             SZ_SetWidth(ColumnWidth[2]);
  735.             SZ_AddLeftOffset(ColumnLeft[2]);
  736.  
  737.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  738.                 SZ_Lines,        2,
  739.                 SZ_AutoWidth,    TRUE,
  740.                 SZ_NewColumn,    TRUE,
  741.             TAG_DONE);
  742.  
  743.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT),NULL);
  744.  
  745.             SZ_SetWidth(ColumnWidth[3]);
  746.             SZ_AddLeftOffset(ColumnLeft[3]);
  747.  
  748.             BoxArray[BoxCounter] = Box = SZ_CreateTextBox(&BoxList,
  749.                 SZ_Lines,        2,
  750.                 SZ_AutoWidth,    TRUE,
  751.                 SZ_NewColumn,    TRUE,
  752.             TAG_DONE);
  753.  
  754.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_TIME_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_ONLINE_TXT),NULL);
  755.  
  756.             if(!Box)
  757.                 AllFine = FALSE;
  758.             else
  759.                 SZ_DrawBoxes(RPort,BoxList);
  760.         }
  761.     }
  762.     else
  763.         AllFine = TRUE;
  764.  
  765.     if((UpdateSig = AllocSignal(-1)) == -1)
  766.         AllFine = FALSE;
  767.     else
  768.         UpdateMask = 1L << UpdateSig;
  769.  
  770.         /* Everything fine so far? */
  771.  
  772.     if(AllFine)
  773.     {
  774.         Forbid();
  775.  
  776.             /* Create the display server task. */
  777.  
  778.         if(StatusDisplayTask = LocalCreateTask("term Status Display Task",5,(TASKENTRY)StatusDisplayServer,4000,0))
  779.             WaitForHandshake();
  780.  
  781.         Permit();
  782.     }
  783.  
  784.         /* Is the display server task up and running? */
  785.  
  786.     if(StatusDisplayTask)
  787.     {
  788.             /* Create a timer device request. */
  789.  
  790.         if(StatusTimePort = (struct MsgPort *)CreateMsgPort())
  791.         {
  792.             if(StatusTimeRequest = (struct timerequest *)CreateIORequest(StatusTimePort,sizeof(struct timerequest)))
  793.             {
  794.                 if(!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)StatusTimeRequest,0))
  795.                 {
  796.                         /* Signal our father process
  797.                          * that we're running.
  798.                          */
  799.  
  800.                     Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  801.  
  802.                     if(RPort)
  803.                     {
  804.                         if(StatusMode == STATUSLINE_COMPRESSED)
  805.                         {
  806.                             Mode = MODE_SCREEN_COMPRESSED;
  807.  
  808.                             SomeObject = RPort;
  809.                         }
  810.                         else
  811.                         {
  812.                             Mode = MODE_SCREEN_NORMAL;
  813.  
  814.                             Carrier.RPort        = RPort;
  815.                             Carrier.BoxArray    = BoxArray;
  816.                             Carrier.BoxList        = BoxList;
  817.  
  818.                             SomeObject = &Carrier;
  819.                         }
  820.  
  821.                         UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,0,0,0);
  822.                     }
  823.  
  824.                     memset(&DeltaTime,0,sizeof(DeltaTime));
  825.                     GetSysTime(&PeriodTime);
  826.  
  827.                         /* Keep on displaying. */
  828.  
  829.                     while(KeepGoing)
  830.                     {
  831.                             /* Are we to quit? */
  832.  
  833.                         if(SetSignal(0,SIG_KILL) & SIG_KILL)
  834.                             KeepGoing = FALSE;
  835.  
  836.                             /* Get the current time. */
  837.  
  838.                         GetSysTime(&Now);
  839.  
  840.                         SafeObtainSemaphoreShared(&OnlineSemaphore);
  841.  
  842.                             /* A connection has just
  843.                              * been established.
  844.                              */
  845.  
  846.                         if(Online && !LocalWasOnline)
  847.                             LocalWasOnline = TRUE;
  848.  
  849.                         ReleaseSemaphore(&OnlineSemaphore);
  850.  
  851.                             /* Print the current time. */
  852.  
  853.                         ThisHour    = (Now.tv_secs % (24 * 60 * 60)) / (60 * 60);
  854.                         ThisMinute    = (Now.tv_secs % (60 * 60)) / 60;
  855.  
  856.                         UpdateInfo(SomeObject,Mode,INFO_CURRENTTIME,ThisHour,ThisMinute,Now.tv_secs % 60);
  857.  
  858.                             /* Handle routine checkup actions. */
  859.  
  860.                         if(PeriodAction = (BOOL)(PeriodTime.tv_secs < Now.tv_secs && Now.tv_secs - PeriodTime.tv_secs >= ROUTINE_CHECK_INTERVAL))
  861.                         {
  862.                             PeriodTime = Now;
  863.  
  864.                             Signal((struct Task *)ThisProcess,SIG_CHECK);
  865.                         }
  866.  
  867.                         SafeObtainSemaphoreShared(&OnlineSemaphore);
  868.                         LocalIsOnline = Online;
  869.                         ReleaseSemaphore(&OnlineSemaphore);
  870.  
  871.                         if(LocalIsOnline)
  872.                         {
  873.                                 /* Show the time we have been online
  874.                                  * so far.
  875.                                  */
  876.  
  877.                             DeltaTime = Now;
  878.  
  879.                             SubTime(&DeltaTime,&OnlineTime);
  880.  
  881.                             if(Now.tv_secs != LastTime.tv_secs)
  882.                             {
  883.                                 UBYTE Sum[20];
  884.                                 WORD What;
  885.  
  886.                                 LastTime = Now;
  887.  
  888.                                 switch(Config->ScreenConfig->TimeMode)
  889.                                 {
  890.                                     case ONLINETIME_TIME:
  891.  
  892.                                         What = SHOW_OnlineTime;
  893.                                         break;
  894.  
  895.                                     case ONLINETIME_COST:
  896.  
  897.                                         What = SHOW_Cost;
  898.                                         break;
  899.  
  900.                                     case ONLINETIME_BOTH:
  901.  
  902.                                         if(PeriodAction)
  903.                                             ShowCounter = (ShowCounter + 1) % 3;
  904.  
  905.                                         switch(ShowCounter)
  906.                                         {
  907.                                             case 0:
  908.  
  909.                                                 What = SHOW_OnlineTime;
  910.                                                 break;
  911.  
  912.                                             case 1:
  913.  
  914.                                                 What = SHOW_Cost;
  915.                                                 break;
  916.  
  917.                                             case 2:
  918.  
  919.                                                 What = SHOW_UnitTime;
  920.                                                 break;
  921.                                         }
  922.  
  923.                                         break;
  924.                                 }
  925.  
  926.                                 OnlineMinutes = DeltaTime.tv_secs / 60;
  927.  
  928.                                 switch(What)
  929.                                 {
  930.                                     case SHOW_OnlineTime:
  931.  
  932.                                         UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(DeltaTime.tv_secs % 86400) / 3600,(DeltaTime.tv_secs % 3600) / 60,DeltaTime.tv_secs % 60);
  933.                                         break;
  934.  
  935.                                     case SHOW_Cost:
  936.  
  937.                                         CreateSum((QueryAccountantCost() + 5000) / 10000,TRUE,Sum,sizeof(Sum));
  938.  
  939.                                         UpdateInfo(SomeObject,Mode,INFO_ONLINECOST,Sum);
  940.                                         break;
  941.  
  942.                                     case SHOW_UnitTime:
  943.  
  944.                                         UpdateInfo(SomeObject,Mode,INFO_UNITTIME,QueryAccountantTime(NULL));
  945.                                         break;
  946.                                 }
  947.                             }
  948.                         }
  949.                         else
  950.                         {
  951.                             if(LocalWasOnline)
  952.                             {
  953.                                 LocalWasOnline = FALSE;
  954.  
  955.                                 UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(DeltaTime.tv_secs % 86400) / 3600,(DeltaTime.tv_secs % 3600) / 60,DeltaTime.tv_secs % 60);
  956.                             }
  957.                         }
  958.  
  959.                             /* Take care of the visual beep
  960.                              * if enabled.
  961.                              */
  962.  
  963.                         if(Beeping)
  964.                         {
  965.                             if(!(BeepCount--))
  966.                             {
  967.                                 Beeping = FALSE;
  968.  
  969.                                 LoadColourTable(VPort,Old,NULL,0);
  970.  
  971.                                 DeleteColourTable(Old);
  972.                                 DeleteColourTable(New);
  973.  
  974.                                 Old = New = NULL;
  975.  
  976.                                     /* Clear the signal bit. */
  977.  
  978.                                 ClrSignal(SIG_BELL);
  979.                             }
  980.                         }
  981.  
  982.                             /* Are we to show a visual beep? */
  983.  
  984.                         if(SetSignal(0,SIG_BELL) & SIG_BELL)
  985.                         {
  986.                             if(Config->TerminalConfig->BellMode == BELL_SYSTEM)
  987.                                 DisplayBeep(Window->WScreen);
  988.                             else
  989.                             {
  990.                                 if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping && (Config->TerminalConfig->BellMode == BELL_VISIBLE || Config->TerminalConfig->BellMode == BELL_BOTH))
  991.                                 {
  992.                                     if(VisualBeep(&Old,&New))
  993.                                     {
  994.                                         LoadColourTable(VPort,New,NULL,0);
  995.  
  996.                                         Beeping = TRUE;
  997.  
  998.                                         BeepCount = 1;
  999.                                     }
  1000.                                 }
  1001.                             }
  1002.                         }
  1003.  
  1004.                             /* Display the current terminal
  1005.                              * status.
  1006.                              */
  1007.  
  1008.                         if(LastStatus != GetStatus())
  1009.                             UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = GetStatus());
  1010.  
  1011.                             /* Show the current transfer
  1012.                              * protocol.
  1013.                              */
  1014.  
  1015.                         if(strcmp(LastProtocol,TransferProtocolName))
  1016.                         {
  1017.                             STRPTR String;
  1018.  
  1019.                             strcpy(LastProtocol,TransferProtocolName);
  1020.  
  1021.                             if(LastProtocol[0])
  1022.                                 String = LastProtocol;
  1023.                             else
  1024.                                 String = "-";
  1025.  
  1026.                             UpdateInfo(SomeObject,Mode,INFO_PROTOCOL,String);
  1027.                         }
  1028.  
  1029.                             /* Show the current baud
  1030.                              * rate.
  1031.                              */
  1032.  
  1033.                         if(LastBaud != Config->SerialConfig->BaudRate)
  1034.                             UpdateInfo(SomeObject,Mode,INFO_BAUDRATE,LastBaud = Config->SerialConfig->BaudRate);
  1035.  
  1036.                             /* Show the current
  1037.                              * terminal font.
  1038.                              */
  1039.  
  1040.                         if(LastFrozen != BufferFrozen)
  1041.                         {
  1042.                             LastFrozen = BufferFrozen;
  1043.  
  1044.                             UpdateInfo(SomeObject,Mode,INFO_BUFFER,LastFrozen != TRUE);
  1045.                         }
  1046.  
  1047.                             /* Show the current terminal
  1048.                              * emulation.
  1049.                              */
  1050.  
  1051.                         if(LastEmulation != Config->TerminalConfig->EmulationMode || (Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL && Stricmp(EmulationName,LastEmulationName)))
  1052.                         {
  1053.                             LastEmulation = Config->TerminalConfig->EmulationMode;
  1054.  
  1055.                             if(Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  1056.                             {
  1057.                                 UpdateInfo(SomeObject,Mode,INFO_EMULATION,EmulationName);
  1058.  
  1059.                                 strcpy(LastEmulationName,EmulationName);
  1060.                             }
  1061.                             else
  1062.                                 UpdateInfo(SomeObject,Mode,INFO_EMULATION,ConfigEmulation[LastEmulation]);
  1063.                         }
  1064.  
  1065.                             /* Show the current serial
  1066.                              * parameters (parity, etc).
  1067.                              */
  1068.  
  1069.                         if(LastBitsPerChar != Config->SerialConfig->BitsPerChar || LastParity != Config->SerialConfig->Parity || LastStopBits != Config->SerialConfig->StopBits)
  1070.                         {
  1071.                             LastBitsPerChar    = Config->SerialConfig->BitsPerChar;
  1072.                             LastParity        = Config->SerialConfig->Parity;
  1073.                             LastStopBits    = Config->SerialConfig->StopBits;
  1074.  
  1075.                             UpdateInfo(SomeObject,Mode,INFO_PARAMETERS,LastBitsPerChar,LastParity,LastStopBits);
  1076.                         }
  1077.  
  1078.                             /* Wait another half a second. */
  1079.  
  1080.                         if(KeepGoing)
  1081.                         {
  1082.                             ULONG    Mask;
  1083.                             BOOL    ResetTime = FALSE;
  1084.  
  1085.                             StatusTimeRequest->tr_node.io_Command    = TR_ADDREQUEST;
  1086.                             StatusTimeRequest->tr_time.tv_secs        = 0;
  1087.                             StatusTimeRequest->tr_time.tv_micro        = MILLION / 2;
  1088.  
  1089.                             SetSignal(0,PORTMASK(StatusTimePort));
  1090.                             SendIO((struct IORequest *)StatusTimeRequest);
  1091.  
  1092.                             FOREVER
  1093.                             {
  1094.                                 Mask = Wait(SIG_BELL | PORTMASK(StatusTimePort) | SIG_CLOSEWINDOW | SIG_RESETTIME | UpdateMask);
  1095.  
  1096.                                 if(Mask & UpdateMask)
  1097.                                 {
  1098.                                     Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  1099.  
  1100.                                     Wait(UpdateMask);
  1101.  
  1102.                                     NeedFullRefresh = TRUE;
  1103.  
  1104.                                     UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = GetStatus());
  1105.                                 }
  1106.  
  1107.                                     /* Close the window and keep quiet? */
  1108.  
  1109.                                 if(Mask & SIG_CLOSEWINDOW)
  1110.                                 {
  1111.                                     Forbid();
  1112.  
  1113.                                     ShakeHands(StatusDisplayTask,SIG_KILL);
  1114.  
  1115.                                     if(BoxList)
  1116.                                     {
  1117.                                         SZ_FreeBoxes(BoxList);
  1118.  
  1119.                                         BoxList = NULL;
  1120.                                     }
  1121.  
  1122.                                     SomeObject = NULL;
  1123.  
  1124.                                     Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  1125.  
  1126.                                     Config->ScreenConfig->StatusLine = STATUSLINE_DISABLED;
  1127.  
  1128.                                     Permit();
  1129.                                 }
  1130.  
  1131.                                 if(Mask & SIG_BELL)
  1132.                                 {
  1133.                                     if(Config->TerminalConfig->BellMode == BELL_SYSTEM)
  1134.                                         DisplayBeep(Window->WScreen);
  1135.                                     else
  1136.                                     {
  1137.                                         if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping && (Config->TerminalConfig->BellMode == BELL_VISIBLE || Config->TerminalConfig->BellMode == BELL_BOTH))
  1138.                                         {
  1139.                                             if(VisualBeep(&Old,&New))
  1140.                                             {
  1141.                                                 LoadColourTable(VPort,New,NULL,0);
  1142.  
  1143.                                                 Beeping = TRUE;
  1144.  
  1145.                                                 BeepCount = 1;
  1146.                                             }
  1147.                                         }
  1148.                                     }
  1149.                                 }
  1150.  
  1151.                                     /* Reset the online time counter. */
  1152.  
  1153.                                 if(Mask & SIG_RESETTIME)
  1154.                                     ResetTime = TRUE;
  1155.  
  1156.                                 if(Mask & PORTMASK(StatusTimePort))
  1157.                                 {
  1158.                                     WaitIO((struct IORequest *)StatusTimeRequest);
  1159.  
  1160.                                     break;
  1161.                                 }
  1162.                             }
  1163.  
  1164.                                 /* Reset the online time. */
  1165.  
  1166.                             if(ResetTime)
  1167.                             {
  1168.                                 ObtainSemaphore(&OnlineSemaphore);
  1169.                                 GetSysTime(&OnlineTime);
  1170.                                 ReleaseSemaphore(&OnlineSemaphore);
  1171.                             }
  1172.                         }
  1173.  
  1174.                             /* Make the colours blink. */
  1175.  
  1176.                         if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping)
  1177.                         {
  1178.                             if(Screen == IntuitionBase->FirstScreen)
  1179.                             {
  1180.                                     /* No main screen window active? */
  1181.  
  1182.                                 if(StatusWindow)
  1183.                                 {
  1184.                                     if(!(Window->Flags & WFLG_WINDOWACTIVE) && !(StatusWindow->Flags & WFLG_WINDOWACTIVE))
  1185.                                         StandardColours = TRUE;
  1186.                                 }
  1187.                                 else
  1188.                                 {
  1189.                                     if(!(Window->Flags & WFLG_WINDOWACTIVE))
  1190.                                         StandardColours = TRUE;
  1191.                                 }
  1192.  
  1193.                                     /* Menu button pressed or window disabled? */
  1194.  
  1195.                                 if(Window->Flags & (WFLG_MENUSTATE | WFLG_INREQUEST))
  1196.                                     StandardColours = TRUE;
  1197.  
  1198.                                     /* User is currently dragging the
  1199.                                      * mouse in order to mark something
  1200.                                      * on the screen?
  1201.                                      */
  1202.  
  1203.                                 if(Marking)
  1204.                                     StandardColours = TRUE;
  1205.  
  1206.                                 Background = FALSE;
  1207.                             }
  1208.                             else
  1209.                             {
  1210.                                 if(!Background)
  1211.                                     StandardColours = TRUE;
  1212.  
  1213.                                 Background = TRUE;
  1214.                             }
  1215.  
  1216.                             if(StandardColours)
  1217.                             {
  1218.                                 if(!SetColours)
  1219.                                 {
  1220.                                     LoadColourTable(VPort,NormalColourTable,NormalColours,PaletteSize);
  1221.  
  1222.                                     SetColours = TRUE;
  1223.                                 }
  1224.  
  1225.                                 StandardColours = FlashIt = FALSE;
  1226.                             }
  1227.                             else
  1228.                             {
  1229.                                     /* Are we to flash the display? */
  1230.  
  1231.                                 if(Config->ScreenConfig->Blinking)
  1232.                                 {
  1233.                                     if(Screen == IntuitionBase->FirstScreen)
  1234.                                     {
  1235.                                         if(FlashIt)
  1236.                                         {
  1237.                                             LoadColourTable(VPort,BlinkColourTable,BlinkColours,PaletteSize);
  1238.  
  1239.                                             SetColours = FALSE;
  1240.                                         }
  1241.                                         else
  1242.                                         {
  1243.                                             LoadColourTable(VPort,NormalColourTable,NormalColours,PaletteSize);
  1244.  
  1245.                                             SetColours = TRUE;
  1246.                                         }
  1247.                                     }
  1248.  
  1249.                                     FlashIt ^= TRUE;
  1250.                                 }
  1251.                             }
  1252.                         }
  1253.                     }
  1254.  
  1255.                     CloseDevice((struct IORequest *)StatusTimeRequest);
  1256.                 }
  1257.  
  1258.                 DeleteIORequest((struct IORequest *)StatusTimeRequest);
  1259.             }
  1260.  
  1261.             DeleteMsgPort(StatusTimePort);
  1262.         }
  1263.  
  1264.         if(Old)
  1265.             LoadColourTable(VPort,Old,NULL,0);
  1266.  
  1267.         DeleteColourTable(Old);
  1268.         DeleteColourTable(New);
  1269.  
  1270.         ShakeHands(StatusDisplayTask,SIG_KILL);
  1271.  
  1272.         if(BoxList)
  1273.             SZ_FreeBoxes(BoxList);
  1274.     }
  1275.  
  1276.     if(UpdateSig != -1)
  1277.         FreeSignal(UpdateSig);
  1278.  
  1279.         /* Signal the father process that we're done
  1280.          * and quietly remove ourselves.
  1281.          */
  1282.  
  1283.     Forbid();
  1284.  
  1285.     Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  1286.  
  1287.     StatusProcess = NULL;
  1288. }
  1289.  
  1290.     /* ForceStatusUpdate():
  1291.      *
  1292.      *    Make sure that the status display gets updated
  1293.      *    as soon as possible.
  1294.      */
  1295.  
  1296. VOID
  1297. ForceStatusUpdate()
  1298. {
  1299.     if(StatusProcess && Window)
  1300.     {
  1301.         ShakeHands((struct Task *)StatusProcess,UpdateMask);
  1302.  
  1303.             /* Ok, the status process is waiting, now update the data */
  1304.  
  1305.         if(Marking)
  1306.             WindowMarkerStop();
  1307.  
  1308.         UpdateTerminalLimits();
  1309.  
  1310.             /* Clear the window */
  1311.  
  1312.         SetAPen(Window->RPort,Pens[BACKGROUNDPEN]);
  1313.         FillBox(Window->RPort,Window->BorderLeft,Window->BorderTop,Window->Width - (Window->BorderLeft + Window->BorderRight),Window->Height - (Window->BorderTop + Window->BorderBottom));
  1314.  
  1315.             /* Restart the status process */
  1316.  
  1317.         Signal((struct Task *)StatusProcess,UpdateMask);
  1318.  
  1319.             /* Repaint the window border, in case it got trashed */
  1320.  
  1321.         RefreshWindowFrame(Window);
  1322.     }
  1323. }
  1324.